Primer on Flexlib’s MDI
Abstract: This provides information on Flexlib’s MDI, which provides the classes for creating a windowing environment within your Flex application, including a window manager.
Overview of Flexlib’s MDI
MDI is an acronym for Multiple Document Interface. MDI windows can be moved, resized, minimized, closed, etc. within a main parent window (as opposed to Single Document Interface where the windows have no parent window and each window appears as a separate item on the taskbar). Flex applications use MDI, with your Flex application and all windows it spawns contained within a web browser such as Firefox, IE, etc. For general info on MDI here is the Wikipedia entry.
The popular open-source Flex library Flexlib provides an MDI framework for Flex apps, not just providing MDIWindows with controls for min/max/close but most importantly providing a manager class for these windows. The manager maintains information on all open windows, and through the manager you can:
- query the state of any managed window (e.g., is it currently minimized?)
- add new windows to be managed
- set global options (e.g., window effects, padding space between tiled windows, etc.)
- perform operations on one or more windows (e.g., move/minimize/maximize/restore a window, cascade or tile all windows, etc.)
The window manager is also the source of events such as windowClose, windowMinimize, cascade.
Since a picture is worth a thousand words I’ve included two screenshots to give you an idea of what this can look like. Below is a screenshot from the MDIExampleExplorer demo app.
The next screencap is from my FTT demo app. Note that one of the MDI windows is minimized (the “Tree View – 105 items” in the lower left corner).
Pictures are nice, but an online demo is even better. The MDIExampleExplorer demo app is here, available through Ben Clinkinbeard’s site.
Having mentioned Ben Clinkinbeard, now is a good time to credit the developers of Flexlib MDI – it was developed by Ben, Brendan Meutzner, and Brian Joseph. If you’re interested in a little MDI history you can watch the Adobe TV 360|Flex video Creating Reusable Components by Ben Clinkinbeard during which Ben gives a little background on the topic. Everyone that uses Flexlib MDI owes this trio a great big thank you – even if Flexlib MDI isn’t exactly what you’re looking for it gives you a great starting point for your own development (source code is available in Flexlib).
Ok, I’ve already fulfilled my goal with this primer – bringing Flexlib MDI to your attention. The remainder of this post will give some basic info on how to obtain it and a few usage tips, but really your best resource on this is the Flexlib site and docs.
Flexlib
For those of you unfamiliar with Flexlib, it’s an open source library of components for Flex. It has a variety of very useful and well designed components. Here are some examples of UICs available in Flexlib (all listed below are used in my FTT demo app):
PromptingTextInput | enhanced text input that displays “ghost” prompting text to the user when the input field is empty |
SuperTabNavigator | enhancement of Flex TabNavigator that lets you drag tabs around, close them, makes the tab list scrollable when there are too many to fit in the available space, etc. |
FlowContainer | a container that “flows” its child UICs similar to how wordWrap wraps text. That is, UICs are added horizontally until there is no more room left on the line, then it starts adding the child UICs on the next “row” of the container. |
Table 1: Some example components from Flexlib
The manifest of Flexlib components is available here. Don’t worry that MDI isn’t listed, when you download Flexlib you’ll find its source code under /src/flexlib/mdi.
The main page for Flexlib, including access to its ASDoc and to a download link is here.
Once you’ve downloaded the Flexlib .zip you’ll find everything you expect from a quality library – not just the swc but also all of the source code, documentation in ASDoc format, and many working examples. To access Flexlib components you make the swc available as you would any swc (e.g., just drop it in your project’s /libs directory and you’re good to go). Of course, you have the source code, so you can also use that.
Flexlib MDI
As noted above, your best source for this info on Flexlib and its MDI is the Flexlib site and docs. However, for the rest of this primer I’ll include some of my own experiences with Flexlib’s MDI, including a couple of gotchas. I considered writing a demo app for this primer but don't have the time right now, and besides the MDIExampleExplorer already covers the basics, and its source code is available in the Flexlib /samples/MDI directory.
Note that an early version of Flexlib’s MDI, a version called flexmdi, also has a google code page (http://code.google.com/p/flexmdi). This Flexmdi page contains links to some useful articles and also another demo app (see the link “Custom buttons in windows”) with source code available. However, keep in mind that this demo app’s codebase is slightly different than the Flexlib MDI codebase. As a result, if you download this demo app’s source code you’ll have to do a little tweaking to use it against Flexlib’s swc. For example, you’ll need to change all the xmlns librefs from “flexmdi” to “flexlib”, change the imports from “flexmdi” to “flexlib.mdi”, etc.
The google code page http://code.google.com/p/flexmdi has some useful info, but this is for a pre-Flexlib version, and the codebase is slightly different. See above for more info... |
in addition to the Flexlib and flexmdi demo apps you can look at my FTT demo app, since its data exploration view makes use of Flexlib MDI. Source code is available, and the best starting point is the DataViewMDI class in the /view package.
Finally, here is a grab bag of Flexlib MDI options/features/references worth highlighting:
- be forewarned that the MDI ASDoc is a bit sparse, and a web search doesn't turn up a lot of useful refs, so be ready to spend a little time reading source code.
- enforceBoundaries option: this is a MDICanvas/MDIManager option used to constrain MDIWindows to the MDICanvas. If you set this to false (default is true) your browser becomes a virtual workspace, giving you a much larger work area (when a window is dragged beyond the MDICanvas boundary you’ll get scrollbars). To see this in action just run my FTT demo app, I use enforceBoundares=false.
- intermittent bug: disappearing window controls. The MDIWindow titlebar holds the min/max/close buttons, but sometimes they disappear when you un-minimize a window. You can address this with a simple workaround as follows:
winID.restore() ; // MDI sometimes omits buttons upon restore so always force them on winID.showControls=true ;
- if you set enforceBoundares=false then you'll likely encounter a problem with "orphan" windows -- that is, the user can drag a window above of its MDI container where the MDIWindow's titlebar may become inaccessible. When that happens the window is "orphaned" (i.e., they can't access the window's titlebar to move it, close it, etc.). Although the user can still use their right mouse button to perform ops on the window, but many users won't realize this. My solution was just to inhibit dragging/dropping the window so that its titlebar becomes inaccessible. Here's some code for this:
First set up an event handler: // Deal w/MDI 'stranded window' bug (ability to drag window off MDIcanvas so titlebar is inaccessible) this.addEventListener(MDIWindowEvent.DRAG_END,repositionOrphan,false,0,true) ; And then have your handler reposition the window at container's Y=0: // Deal with MDI bug that allows you to drag window so it is stranded above top of MDICanvas protected function repositionOrphan(e:Event):void { if (this.y < 0) y=0 ; }
- for info on adding controls to the titlebar you might want to watch the Adobe TV 360|Flex video Creating Reusable Components by Ben Clinkinbeard in which Ben describes the design and shows some code for performing this task. Also possibly useful is this posting. A warning: the old flexmdi site has a demo on adding controls but this is not very useful since the method for adding controls changed when flexmdi moved into Flexlib (you no longer use an addControl method, adding controls is done through MDIWindowControlsContainer). Again, I recommmend Ben's ATV video for some general info on this topic.
- Brian Joseph has some useful posts on flexMDI (pre-Flexlib version) at his site, and for more info on the Flexlib window manager you might find his article on this topic useful: brianjoseph31.typepad.com/smashedapples post on Flex MDI managers
- also useful are Ben’s series of posts on the topic: Ben Clinkinbeard's Flex MDI post
For more info on Flexlib MDI you should refer to their demo apps and ASDoc and online resources (admittedly the doc is pretty sparse, so be prepared to spend time reading some code). Bottom line, Flexlib MDI is very useful -- anyone looking for a Flex window manager should certainly take a look at it. As I said above, Flexlib MDI may not be 100% what you want, but it’s a great starting point, and we owe Ben, Brendan and Brian a big thank you.